package org.test.client.ui.skinui.btn;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;

import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JRadioButton;
import javax.swing.JToolBar;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.ButtonUI;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.InsetsUIResource;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicButtonUI;
import javax.swing.text.JTextComponent;

import org.jb2011.ninepatch4j.NinePatch;
import org.test.client.ui.util.UIUtil;

/**
 * 利用ninepatch 构造的 button UI
 *  关于图片缓存 暂时没有添加
 * @author Guodeqi
 *
 */

public class MyButtonUI extends BasicButtonUI{
	private static final String GENERAL_DEFAULT_PATH = "res/btn_general_default.9.png";
	private static final String GENERAL_PRESSED_PATH = "res/btn_general_pressed.9.png";
	private static final String GENERAL_ROVER_PATH = "res/btn_general_rover.9.png";
	
	private static final String SPECIAL_BLUE_PATH = "res/btn_special_blue.9.png";
	private static final String SPECIAL_DEFAULT_PATH = "res/btn_special_default.9.png";//green
	private static final String SPECIAL_DISABLED_PATH = "res/btn_special_disabled.9.png";
	private static final String SPECIAL_LB_PATH = "res/btn_special_lightblue.9.png";
	private static final String SPECIAL_RED_PATH = "res/btn_special_red.9.png";
	
	private static final String SPECIAL_LB_ROVER_PATH = "res/lightBlueRover.9.png";
	
	private static NinePatch npGeneralDefalut = null;
	private static NinePatch npGeneralPressed = null;
	private static NinePatch npGeneralRover = null;

	private static NinePatch npSpecialBlue= null;
	private static NinePatch npSpecialDefault = null;
	private static NinePatch npSpecialDisabled = null;
	private static NinePatch npSpecialLb = null;
	private static NinePatch npSpecialRed = null;
	private static NinePatch npLBRover = null;
	
	private static NinePatch whiteBtn = null;
	
	static{
		try {
			npGeneralDefalut = NinePatch.load(MyButtonUI.class.getResource(GENERAL_DEFAULT_PATH), false);
			npGeneralPressed = NinePatch.load(MyButtonUI.class.getResource(GENERAL_PRESSED_PATH), false);
			npGeneralRover = NinePatch.load(MyButtonUI.class.getResource(GENERAL_ROVER_PATH), false);

			npSpecialBlue = NinePatch.load(MyButtonUI.class.getResource(SPECIAL_BLUE_PATH), false);
			npSpecialDefault = NinePatch.load(MyButtonUI.class.getResource(SPECIAL_DEFAULT_PATH), false);
			npSpecialDisabled = NinePatch.load(MyButtonUI.class.getResource(SPECIAL_DISABLED_PATH), false);
			npSpecialLb = NinePatch.load(MyButtonUI.class.getResource(SPECIAL_LB_PATH), false);
			npSpecialRed = NinePatch.load(MyButtonUI.class.getResource(SPECIAL_RED_PATH), false);
			npLBRover = NinePatch.load(MyButtonUI.class.getResource(SPECIAL_LB_ROVER_PATH), false);
			
			whiteBtn = NinePatch.load(MyButtonUI.class.getResource(GENERAL_DEFAULT_PATH), false);
		} catch (Exception e) {
			e.printStackTrace();
		}
		doInit();
	}
	
	/**
	 * 此处放入的  属性 在其他组件中有用到 例如：RadioBtn
	 */
	private static void doInit() {
		
		//以下属性将决定按钮获得焦点时的焦点虚线框的绘制偏移量哦
		UIManager.put("Button.dashedRectGapX",3);//windows LNF中默认是3
		UIManager.put("Button.dashedRectGapY",3);//windows LNF中默认是3
		UIManager.put("Button.dashedRectGapWidth",6);//windows LNF中默认是6
		UIManager.put("Button.dashedRectGapHeight",6);//windows LNF中默认是6
		
//		UIManager.put("ButtonUI",org.jb2011.lnf.beautyeye.ch3_button.BEButtonUI.class.getName());
//		UIManager.put("Button.margin",new InsetsUIResource(6, 8, 6, 8));//new InsetsUIResource(6, 8, 6, 8));
		//此border可以与Button.margin连合使用，而者之和即查整个Button的内衬哦
//		UIManager.put("Button.border" ,new org.jb2011.lnf.beautyeye.ch3_button.BEButtonUI
//					.XPEmptyBorder(new Insets(3,3,3,3)));//default is 3,3,3,3
		//获得焦点时的虚线框颜色
		UIManager.put("Button.focus",new ColorUIResource(130,130,130));
	}
	
	private static final int dashedRectGapX = 3;
	private static final int dashedRectGapY = 3;
	private static final int dashedRectGapWidth = 6;
	private static final int dashedRectGapHeight = 6;
	private static final Color focusColor = new ColorUIResource(130,130,130);

	
	private static MyButtonUI buttonUI = new MyButtonUI();
	private static MyButtonUI WarningUI = null;
	private static MyButtonUI SuccessUI = null;
	private static MyButtonUI InfoUI = null;
	private static MyButtonUI whiteUI = null;

	private Insets insets = null;

	public static ButtonUI createUI(JComponent jcomponent) {
		return buttonUI;
	}

	public static ButtonUI createWarningBtnUI(JComponent jcomponent){
		if(WarningUI == null){
			WarningUI = new MyButtonUI();
			WarningUI.buttonType = NormalColor.warnning;
		}
		return WarningUI;
	}

	
	public static ButtonUI createWhiteBtnUI(JComponent jcomponent){
		if(whiteUI == null){
			whiteUI = new MyButtonUI();
			whiteUI.buttonType = NormalColor.white;
		}
		return whiteUI;
	}
	
	public static ButtonUI createSuccessBtnUI(JComponent jcomponent){
		if(SuccessUI == null){
			SuccessUI = new MyButtonUI();
			SuccessUI.buttonType = NormalColor.success;
		}
		return SuccessUI;
	}
	
	public static ButtonUI createInfoBtnUI(JComponent jcomponent){
		if(InfoUI == null){
			InfoUI = new MyButtonUI();
			InfoUI.buttonType = NormalColor.info;
		}
		return InfoUI;
	}
	
	private NormalColor buttonType = NormalColor.normal;
	
	private MyButtonUI() {
	}

	
	private MyButtonUI(NormalColor buttonType) {
		this.buttonType = buttonType;
	}

	@Override
	protected void paintFocus(Graphics g, AbstractButton b,
			Rectangle viewRect, Rectangle textRect, Rectangle iconRect) {
		
		int width = b.getWidth();
		int height = b.getHeight();
		g.setColor(focusColor);
		UIUtil.drawDashedRect(g, dashedRectGapX, dashedRectGapY, width - dashedRectGapWidth, height - dashedRectGapHeight);
		// 立体阴影就是向右下偏移一个像素实现的
		g.setColor(new Color(255, 255, 255, 50));
		UIUtil.drawDashedRect(g, dashedRectGapX + 1, dashedRectGapY + 1, width
				- dashedRectGapWidth, height - dashedRectGapHeight);
	}
	
	@Override
	public void paint(Graphics g, JComponent jcomponent) {
		AbstractButton btn = (AbstractButton)jcomponent;
		Graphics2D g2d = (Graphics2D)g;
//		boolean toolbar = (btn.getParent() instanceof JToolBar);
//		if(!toolbar){
//			Dimension pSize = btn.getPreferredSize();
//			btn.setPreferredSize(new Dimension(pSize.width,pSize.height));
//		}
		paintBackground(btn,g2d);
		insets = new Insets(1,5,1,4);
		btn.setBorder(new XPEmptyBorder(insets));
		super.paint(g, jcomponent);
	}
	
	private void paintBackground(AbstractButton btn, Graphics2D g2d) {
		Dimension size = btn.getSize();
		Dimension pSize = btn.getPreferredSize();
		int dx = 0;
		int dy = 0;
		int dw = Math.max(size.width, pSize.width);
		int dh = Math.max(size.height, pSize.height);
		ButtonModel model = btn.getModel();
		
		
		if (model.isArmed() && model.isPressed() || model.isSelected()){
			if(buttonType == NormalColor.normal){
				npGeneralPressed.draw(g2d, dx, dy, dw, dh);
			}else{
				NinePatchExt.drawPressed(getNinePatchByNormalColor(buttonType),g2d, dx, dy, dw, dh);
			}
		}else if (!model.isEnabled()){
			npSpecialDisabled.draw(g2d, dx, dy, dw, dh);
		}else if (model.isRollover()){
			if(buttonType == NormalColor.normal){
				npGeneralRover.draw(g2d, dx, dy, dw, dh);
			}else{
				NinePatchExt.drawRover(getNinePatchByNormalColor(buttonType),g2d, dx, dy, dw, dh);
			}
		}
		else {
			getNinePatchByNormalColor(buttonType).draw(g2d, dx, dy, dw, dh);
		}
			
	}
	
	private NinePatch getNinePatchByNormalColor(NormalColor color){
		if (buttonType == NormalColor.success) {
			return npSpecialDefault;
		} else if (buttonType == NormalColor.warnning) {
			return npSpecialRed;
		} else if (buttonType == NormalColor.basic) {
			return npSpecialBlue;
		} else if (buttonType == NormalColor.info) {
			return npSpecialLb;
		} else if (buttonType == NormalColor.white) {
			return whiteBtn;
		} else
			return npGeneralDefalut;
	}
	
	@Override
	public Dimension getPreferredSize(JComponent jcomponent) {
		 Dimension pSize = super.getPreferredSize(jcomponent);
		return new Dimension(pSize.width,pSize.height+4);
//		return pSize;
	}
	
	static enum NormalColor {

		/** 普通灰色按钮. 默认 */
		normal,

		/** 绿色按钮. 成功按钮 */
		success,

		/** 红色按钮. 危险按钮 */
		warnning,

		/** 浅蓝色按钮. 信息按钮 */
		info,

		/** 深蓝色按钮. 原始按钮 */
		basic,
		
		white
	}
}



// copy from XPStyle.XPEmptyBorder 代码没有修改
/**
 * The Class XPEmptyBorder.
 * 这里 给按钮 设置 这个边框的是因为 ： 需要重写getBorderInsets(Component c, Insets insets)方法
 * 如果按钮不在 toolbar中的时候， 可以 增大 margin 提高视觉感官
 * 
 */
class XPEmptyBorder extends EmptyBorder implements UIResource {

	/**
	 * Instantiates a new xP empty border.
	 *
	 * @param m
	 *            the m
	 */
	public XPEmptyBorder(Insets m) {
		super(m.top + 2, m.left + 2, m.bottom + 2, m.right + 2);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * javax.swing.border.AbstractBorder#getBorderInsets(java.awt.Component)
	 */
	public Insets getBorderInsets(Component c) {
		return getBorderInsets(c, getBorderInsets());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.swing.border.EmptyBorder#getBorderInsets(java.awt.Component,
	 * java.awt.Insets)
	 */
	public Insets getBorderInsets(Component c, Insets insets) {
		insets = super.getBorderInsets(c, insets);

		Insets margin = null;
		if (c instanceof AbstractButton) {
			Insets m = ((AbstractButton) c).getMargin();
			// if this is a toolbar button then ignore getMargin()
			// and subtract the padding added by the constructor
			if (c.getParent() instanceof JToolBar
					&& !(c instanceof JRadioButton)
					&& !(c instanceof JCheckBox)
					&& m instanceof InsetsUIResource) {
				insets.top -= 2;
				insets.left -= 2;
				insets.bottom -= 2;
				insets.right -= 2;
			} else {
				margin = m;
			}
		} else if (c instanceof JToolBar) {
			margin = ((JToolBar) c).getMargin();
		} else if (c instanceof JTextComponent) {
			margin = ((JTextComponent) c).getMargin();
		}
		if (margin != null) {
			insets.top = margin.top + 2;
			insets.left = margin.left + 2;
			insets.bottom = margin.bottom + 2;
			insets.right = margin.right + 2;
		}
		return insets;
	}
}
